package com.binguo.api.service;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.binguo.api.form.*;

import com.binguo.api.result.Result;
import com.binguo.api.result.ResultGenerator;
import com.binguo.common.enums.CardType;

import com.binguo.common.exception.ServiceException;
import com.binguo.common.util.EncryptUtils;
import com.binguo.common.util.PriceUtil;
import com.binguo.common.util.UrlUtils;

import com.binguo.helper.FaceHelperV3;
import com.binguo.model.api.dto.OrderItemDTO;
import com.binguo.model.mapper.*;
import com.binguo.model.model.*;
import com.binguo.model.repository.*;

import org.apache.poi.ss.formula.functions.Now;
import org.python.compiler.APIVersion;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Condition;


import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class ApiService {

    @Autowired
    private PayCardRepository payCardRepository;
    @Autowired
    private ShopRepository shopRepository;
    @Autowired
    private ProductCategoryRepository productCategoryRepository;
    @Resource
    private ProductCategoryMapper productCategoryMapper;
    @Autowired
    private ProductRepository productRepository;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private RenShouTangService renShouTangService;
    @Autowired
    private CustomerRepository customerRepository;
    @Resource
    private CustomerMapper customerMapper;
    @Resource
    private CustomerExtendMapper customerExtendMapper;
    @Resource
    private PayCardMapper payCardMapper;
    @Autowired
    private FaceRepository faceRepository;
    @Resource
    private BinguoOrderMapper binguoOrderMapper;
    @Autowired
    private OrderItemRepository orderItemRepository;

    /**
     * 云澎api支付接口
     * @param apiPayForm
     * @param url
     * @return
     * @throws IOException
     */
    public Result pay(ApiForm<ApiPayForm> apiPayForm, String url)throws IOException {
        Shop shop = shopRepository.findById(apiPayForm.getShopId());
        apiPayForm.setAppId(shop.getAppId());
        TreeMap<String, Object> param =  new TreeMap();
        param.put("orderNo",apiPayForm.getForm().getOrderNo());
        param.put("payType",apiPayForm.getForm().getPayType().toString());
        param.put("shopId",apiPayForm.getShopId().toString());
        param.put("branchId",apiPayForm.getBranchId());
        param.put("appId",apiPayForm.getAppId());
        apiPayForm.setSign(generateSign(param,shop.getSecurityKey()));
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(apiPayForm));
        Map<String, Object> map = JSONObject.toJavaObject(JSONObject.parseObject(UrlUtils.send(url,jsonObject,"utf-8")), Map.class);
        if(Integer.valueOf(String.valueOf(map.get("error_code")))==0){

            Map<String, String>  dataMap = JSONObject.toJavaObject(JSONObject.parseObject(String.valueOf(map.get("data"))), Map.class);
            if(dataMap.get("success").equals("true")){
                //当支付类型为卡支付时dataMap返回余额
                if(apiPayForm.getForm().getPayType().getCode()==0){
                    Condition condition = new Condition(PayCard.class);
                    condition.or().andEqualTo("cardNo",dataMap.get("cardNo"));
                    //更新当前账户余额
                    payCardRepository.updateByCondition(
                            PayCard.builder().cardno(dataMap.get("cardNo")).
                                    yktAccountbalance(
                            new BigDecimal(dataMap.get("balance")).multiply(new BigDecimal("100")).longValue()).
                                    build(),condition);

                    int amount = 0;
                    List<OrderItem> orderItems = new ArrayList<>();
                    for(OrderItemDTO orderItemDTO : apiPayForm.getForm().getItems()){
                        amount += orderItemDTO.getPrice();
                        OrderItem orderItem = new OrderItem();
                        orderItem.setId(0);
                        orderItem.setOrderno(apiPayForm.getForm().getOrderNo());
                        Condition condit = new Condition(Product.class);
                        condition.or().andEqualTo("searchcode",orderItemDTO.getProductId());
                        List<Product> productList = productRepository.findByCondition(condition);
                        orderItem.setProductid(productList.get(0).getId());
                        orderItem.setProductname(productList.get(0).getName());
                        orderItem.setPrice(new BigDecimal(orderItemDTO.getPrice()).multiply(new BigDecimal("100")).longValue());
                        orderItem.setRealprice(new BigDecimal(orderItemDTO.getPrice()).multiply(new BigDecimal("100")).longValue());
                        orderItem.setQuantity(orderItemDTO.getQuantity());
                        orderItem.setCreated(new Date());
                        orderItem.setUpdated(new Date());
                        orderItems.add(orderItem);

                    }
                    BinguoOrder binguoOrder = BinguoOrder.builder().branchid(apiPayForm.getBranchId()).id(0).realfee(apiPayForm.getForm().
                            getTotalFee()).realfee(apiPayForm.getForm().getRealFee()).
                            customerid(apiPayForm.getForm().getCustomerId()).customerphone(apiPayForm.getForm().getCustomerPhone()).
                            serialnumber(apiPayForm.getForm().getSerialNumber()).ordertype(1).shopid(apiPayForm.getShopId()).
                            orderno(apiPayForm.getForm().getOrderNo()).totalquantity(amount).paystatus(new Byte("1")).
                            paytime(new Date()).created(new Date()).updated(new Date()).
                            source(new Byte(apiPayForm.getForm().getPayType().getCode().toString())).build();
                    //binguoOrder.setCustomername(ct.getName());
                   /* if(order.getPayType() == 0 && null != order.getCardNo()){
                        binguoOrder.setCardno(order.getCardNo());
                    }*/

                    //保存订单
                    binguoOrderMapper.insertSelective(binguoOrder);
                    //保存订单详细
                    orderItemRepository.save(orderItems);

                }
                return ResultGenerator.genSuccessResult(map);
            }else{

                return ResultGenerator.genFailResult("支付失败,请重试！");
            }
        }else{

            return ResultGenerator.genFailResult("请求失败！");
        }
    }

    /**
     * 云澎api菜品被动接收接口
     * @param apiPayForm
     * @return
     */
    public Result product(ApiForm<ApiProductForm> apiPayForm){
        Shop shop = shopRepository.findById(apiPayForm.getShopId());
        apiPayForm.setAppId(shop.getAppId());
        TreeMap<String, Object> param =  new TreeMap();
        param.put("shopId",apiPayForm.getShopId().toString());
        param.put("branchId",apiPayForm.getBranchId());
        param.put("product",apiPayForm.getList());
        param.put("appId",apiPayForm.getAppId());
        //生成签名
        String sign = generateSign(param,shop.getSecurityKey());

        //判断签名
        if(apiPayForm.getSign() != null && sign.equals(apiPayForm.getSign())){
            for(ApiProductForm product : apiPayForm.getList()){
                //添加菜品
               Product pro =  Product.builder().id(0).name(product.getName()).
                       price(PriceUtil.getRealPrice(String.valueOf(product.getPrice()))).
                       searchcode(product.getId().toString()).shopid(apiPayForm.getShopId()).build();
               List<ProductCategory> productCategoryList = new ArrayList<>();
               Condition condition = new Condition(ProductCategory.class);
               condition.or().andEqualTo("shopid",apiPayForm.getShopId()).
                       andEqualTo("name",product.getCategoryName());
                productCategoryList = productCategoryRepository.findByCondition(condition);
                //先判断分类是否存在，如果有则拿到分类id
               if(productCategoryList.size()>0){
                   pro.setMinorcategoryid(productCategoryList.get(0).getId());
               }else{
                   //如果没有则新增分类名并返回分类id
                   ProductCategory productCategory = ProductCategory.builder().id(0).deleted(false).name(product.getCategoryName()).
                           shopid(apiPayForm.getShopId()).parentid(0).type(new Byte("1")).build();
                   //插入返回主键
                   productCategoryMapper.insertSelective(productCategory);
                   pro.setMinorcategoryid(productCategory.getId());
               }
               //判断当前菜品是否已经添加
                condition = new Condition(Product.class);
                condition.or().andEqualTo("searchcode",product.getId());
                //searchcode是唯一值，所以返回结果size为1
                List<Product> productList = productRepository.findByCondition(condition);

                if(null != product.getImgUrl()){
                    pro.setProductpic(product.getImgUrl());
                    if(productList.size()>0){
                        //如果已经添加则更新
                        productList.get(0).setPrice(pro.getPrice());
                        productList.get(0).setName(pro.getName());
                        if (!productList.get(0).getProductpic().equals(pro.getProductpic())) {
                            //图片变化时，删除已有图片
                            renShouTangService.delImg(pro.getId(),apiPayForm.getBranchId());
                            //添加新图片
                            renShouTangService.addImg(pro.getId(), pro.getProductpic(),apiPayForm.getBranchId());
                        }
                        productMapper.updateByPrimaryKey(productList.get(0));

                    }else{
                        //如果没添加过则新增
                        productMapper.insertSelective(pro);
                        //添加新图片
                        renShouTangService.addImg(pro.getId(), product.getImgUrl(),apiPayForm.getBranchId());
                    }
                }

            }
        }else{
            return ResultGenerator.genFailResult("签名不合法！");
        }
        return ResultGenerator.genSuccessResult("操作成功！");
    }

    public Result customer(ApiForm<ApiCustomerForm> apiForm){
        if (StringUtils.isEmpty(apiForm.getShopId())
                || StringUtils.isEmpty(apiForm.getBranchId())
                || StringUtils.isEmpty(apiForm.getSign())
                || StringUtils.isEmpty(apiForm.getList())
        ) {
            throw new ServiceException("参数错误");
        }
        for(ApiCustomerForm cus : apiForm.getList()){
            if (StringUtils.isEmpty(cus.getName())
                    || StringUtils.isEmpty(cus.getPhone())
            ) {
                throw new ServiceException("参数错误");
            }
        }
        Shop shop = shopRepository.findById(apiForm.getShopId());
        apiForm.setAppId(shop.getAppId());
        TreeMap<String, Object> param =  new TreeMap();
        param.put("shopId",apiForm.getShopId().toString());
        param.put("branchId",apiForm.getBranchId());
        param.put("customer",apiForm.getList());
        param.put("appId",apiForm.getAppId());
        String faceID = "";
        //生成签名
        String sign = generateSign(param,shop.getSecurityKey());
        //判断签名一致性
        if(apiForm.getSign() != null && sign.equals(apiForm.getSign())){
            //遍历用户列表
            for(ApiCustomerForm customer : apiForm.getList()){

                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = new Date();
                try {
                    date = simpleDateFormat.parse(simpleDateFormat.format(date.getTime()));
                } catch(ParseException px) {
                    px.printStackTrace();
                }
                Customer cus = Customer.builder().id(0).name(customer.getName()).
                        phone(customer.getPhone()).created(date).updated(date).build();
                CustomerExtend cusExtend = CustomerExtend.builder().id(0).isAudit(0).
                        groupName("普通会员").shopId(apiForm.getShopId()).groupId(0).build();
                Customer ct = customerMapper.getCustomerByPhone(customer.getPhone());
                if(null == ct){
                    //不存在则需要新增
                    //customer表
                    customerMapper.insertSelective(cus);
                    //customerExtend表
                    customerExtendMapper.insertSelective(cusExtend);
                    ct = customerMapper.getCustomerByPhone(customer.getPhone());
                    faceID = createPayCardAndFace(cus.getId(),customer.getFaceUrl(),shop.getName(),apiForm.getShopId(),customer.getCardNo());
                    System.out.println(faceID);
                }else{
                    //存在用户
                    ct.setName(customer.getName());
                    //更新用户信息
                    customerRepository.update(ct);
                    cusExtend = customerExtendMapper.getByShopIdAndCustomerId(apiForm.getShopId(),ct.getId());
                    if(null == cusExtend){
                        //customerExtend表
                        customerExtendMapper.insertSelective(cusExtend);
                    }else{
                        //无论如何设置user_audit为1
                        customerExtendMapper.updateCustomerExtend(ct.getId(),apiForm.getShopId());
                    }
                    //如果人脸不为空则添加人脸
                    if(null != customer.getFaceUrl()){
                        //已经创建过
                        Condition tempFaceExample = new Condition(Face.class);
                        tempFaceExample.or().andEqualTo("customerId",ct.getId())
                                .andEqualTo("persionid", apiForm.getShopId() + "_" + ct.getId())
                        ;
                        List<Face> tempFaceList = faceRepository.findByCondition(tempFaceExample);


                        if (tempFaceList != null && tempFaceList.size() > 0) {
                            for (Face face : tempFaceList) {
                                if (face.getFaceurl().equals(customer.getFaceUrl())) {

                           throw new ServiceException("此图片已经添加");
                                }
                            }

                        }else {

                            faceID = FaceHelperV3.addFace(apiForm.getShopId() + "_" + ct.getId(), customer.getFaceUrl());

                        }

                    }
                }

                if("".equals(faceID)){
                    throw new ServiceException("人脸添加失败");
                }else{
                    Face temp = new Face();
                    temp.setFaceid(faceID);
                    temp.setCustomerId(ct.getId());
                    temp.setFaceurl(customer.getFaceUrl());
                    temp.setPersionid(apiForm.getShopId() + "_" + ct.getId());
                    faceRepository.save(temp);
                }

            }

        }else{
            return ResultGenerator.genFailResult("签名不合法！");
        }
        return ResultGenerator.genSuccessResult("操作成功！");
    }

    /**
     *订单
     * @param apiForm
     * @return
     */
    public Result order(ApiForm<ApiOrderForm> apiForm){
        if (StringUtils.isEmpty(apiForm.getShopId())
                || StringUtils.isEmpty(apiForm.getBranchId())
                || StringUtils.isEmpty(apiForm.getSign())
                || StringUtils.isEmpty(apiForm.getList())
        ) {
            throw new ServiceException("参数错误");
        }
        for(ApiOrderForm order : apiForm.getList()){
            if (StringUtils.isEmpty(order.getPhone())
                    || StringUtils.isEmpty(order.getOrderNo())
                    || StringUtils.isEmpty(order.getTotalFee())
                    || StringUtils.isEmpty(order.getPayType())
                    || StringUtils.isEmpty(order.getProduct())
                    || StringUtils.isEmpty(order.getPayTime())
            ) {
                throw new ServiceException("参数错误");
            }
            for(ApiProductForm product :order.getProduct()){
                if (StringUtils.isEmpty(product.getId() )
                        || StringUtils.isEmpty(product.getPrice())
                        || StringUtils.isEmpty(product.getAmount())
                ) {
                    throw new ServiceException("参数错误");
                }
            }
        }

        Shop shop = shopRepository.findById(apiForm.getShopId());
        apiForm.setAppId(shop.getAppId());
        TreeMap<String, Object> param =  new TreeMap();
        param.put("shopId",apiForm.getShopId().toString());
        param.put("branchId",apiForm.getBranchId());
        param.put("order",apiForm.getList());
        param.put("appId",apiForm.getAppId());
        //生成签名
        String sign = generateSign(param,shop.getSecurityKey());
        if (apiForm.getSign() != null && sign.equals(apiForm.getSign()) && null != apiForm.getList()){
            for(ApiOrderForm order : apiForm.getList()){
                BinguoOrder binguoOrder = new BinguoOrder();
                if(null != order.getCardNo()){
                    PayCard payCard = payCardMapper.selectPayCardByCardNo(order.getCardNo());
                    if(null == payCard){
                        throw new ServiceException("卡号错误");

                    }
                    binguoOrder.setCardno(order.getCardNo());
                    binguoOrder.setCardid(payCard.getId());
                }
                binguoOrder.setId(0);
                binguoOrder.setRealfee(new BigDecimal(order.getTotalFee()).multiply(new BigDecimal("100")).longValue());
                Customer ct = customerMapper.getCustomerByShopIdAndPhone(apiForm.getShopId(),order.getPhone());
                if(null == ct){
                    throw new ServiceException("会员不存在！");

                }
                binguoOrder.setCustomerid(ct.getId());
                binguoOrder.setBranchid(apiForm.getBranchId());
                binguoOrder.setSerialnumber(order.getOrderNo());
                binguoOrder.setOrdertype(1);
                binguoOrder.setShopid(Integer.valueOf(apiForm.getShopId()));
                binguoOrder.setOrderno(order.getOrderNo());
                binguoOrder.setTotalfee(new BigDecimal(order.getTotalFee()).multiply(new BigDecimal("100")).longValue());
                int amount = 0;
                List<OrderItem> orderItems = new ArrayList<>();
                for(ApiProductForm productForm : order.getProduct()){
                    amount += productForm.getAmount();
                    OrderItem orderItem = new OrderItem();
                    orderItem.setId(0);
                    orderItem.setOrderno(order.getOrderNo());
                    Condition condition = new Condition(Product.class);
                    condition.or().andEqualTo("searchcode",productForm.getId());
                    List<Product> productList = productRepository.findByCondition(condition);
                    orderItem.setProductid(productList.get(0).getId());
                    orderItem.setProductname(productForm.getName());
                    orderItem.setPrice(new BigDecimal(productForm.getPrice()).multiply(new BigDecimal("100")).longValue());
                    orderItem.setRealprice(new BigDecimal(productForm.getPrice()).multiply(new BigDecimal("100")).longValue());
                    orderItem.setQuantity(productForm.getAmount());
                    orderItem.setCreated(order.getPayTime());
                    orderItem.setUpdated(order.getPayTime());
                    orderItems.add(orderItem);
                }
                binguoOrder.setTotalquantity(amount);
                binguoOrder.setCustomername(ct.getName());
                binguoOrder.setCustomerphone(order.getPhone());
                if(order.getPayType() == 0 && null != order.getCardNo()){
                    binguoOrder.setCardno(order.getCardNo());
                }
                binguoOrder.setPaystatus(new Byte("1"));
                binguoOrder.setPaytime(order.getPayTime());
                binguoOrder.setCreated(order.getPayTime());
                binguoOrder.setUpdated(order.getPayTime());
                binguoOrder.setSource(new Byte(order.getPayType().toString()));
                //保存订单
                binguoOrderMapper.insertSelective(binguoOrder);
                //保存订单详细
                orderItemRepository.save(orderItems);

            }
        }else{
            return ResultGenerator.genFailResult("签名不合法！");
        }
        return ResultGenerator.genSuccessResult("操作成功！");
    }

    private static String generateSign(Map<String, Object> param, String appKey) {
        StringBuilder sb = new StringBuilder();

        for (Map.Entry<String,Object> en : param.entrySet()) {
            sb.append(en.getKey()).append("=").append(en.getValue()).append("&");
        }
        sb.append("key=").append(appKey);

        String sign = EncryptUtils.md5(sb.toString()).toUpperCase();
        return sign;
    }



    private String createPayCardAndFace(Integer customerId, String faceUrl, String shopName,Integer shopId,String cardNo){
        PayCard payCard = PayCard.builder()
                .shopid(Integer.valueOf(shopId))
                .customerid(customerId)
                .cardtype(CardType.BINGUO_CARD.getCode().byteValue())
                .deleted(false)
                .name(shopName + "卡")
                .wxAccountbalance(0l)
                .bzAccountbalance(0l)
                .yktAccountbalance(0l)
                .accountbalance(0l)
                .ismaster(true)
                .isnopasswordpay(true)
                .build();

        payCardMapper.insertSelective(payCard);

        PayCard tempPaycard = new PayCard();
        if(null == cardNo){
            tempPaycard.setCardno(payCard.getId() + "");
        }else{
            tempPaycard.setCardno(cardNo);
        }
        tempPaycard.setId(payCard.getId());
        payCardMapper.updateByPrimaryKeySelective(tempPaycard);

        addCustomerExtend(customerId,shopId);

        if(null != faceUrl){
            String faceID = FaceHelperV3.createPerson(String.valueOf(shopId),
                    shopId + "_" + customerId, faceUrl);
            if(null == faceID){
                throw new ServiceException("人脸添加失败");
            }
            return faceID;
        }
        return null;

    }
    private void addCustomerExtend(Integer customerId,Integer shopId) {
        Condition customerExtendCondition = new Condition(CustomerExtend.class);
        customerExtendCondition.or().andEqualTo("customerId", customerId)
                .andEqualTo("shopId", shopId)
        ;
        List<CustomerExtend> customerExtendList =
                customerExtendMapper.selectByCondition(customerExtendCondition);

        if (customerExtendList != null && customerExtendList.size() > 0) {
            CustomerExtend customerExtend = customerExtendList.get(0);

            if (customerExtend.getIsAudit().intValue() == 0) {
                CustomerExtend temp = new CustomerExtend();
                temp.setIsAudit(1);
                temp.setId(customerExtend.getId());

                customerExtendMapper.updateByPrimaryKeySelective(temp);
            }
        }else {
            CustomerExtend customerExtend = new CustomerExtend();
            customerExtend.setShopId(shopId);
            customerExtend.setCustomerId(customerId);
            customerExtend.setUserStatus(1);
            customerExtend.setIsAudit(1);
            customerExtendMapper.insertSelective(customerExtend);
        }
    }
}
